package org.example.handler;

import lombok.SneakyThrows;
import org.dom4j.DocumentException;
import org.example.anno.MapperScan;
import org.example.config.Configurations;
import org.example.dto.SqlData;
import org.example.session.Session;
import org.example.session.SessionInit;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.type.AnnotationMetadata;

import java.beans.PropertyVetoException;
import java.io.File;
import java.lang.reflect.*;
import java.util.List;
import java.util.Map;

public class RegisterBeanMapperHandler implements ImportBeanDefinitionRegistrar, Session {

    private Configurations configuration;
    @SneakyThrows
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        if (!importingClassMetadata.isAnnotated(MapperScan.class.getName())) {
            return;
        }
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName());
        String value = (String) annotationAttributes.get("value");

        //configuration = SessionInit.init();
        System.out.println(value);
        readMapperPackageData(value);
    }

    public <T> T readMapperPackageData(String path)
    {
        File foldFiles = new File(path);
        if (!foldFiles.exists())
        {
            System.out.println("文件路径不存在");
        }
        File[] files = foldFiles.listFiles((file, name) -> {
            return name.endsWith(".java");
        });
        for (File file : files) {
            System.out.println(file.getName());
        }

        return null;
    }

    @Override
    public <E> List<E> selectList(SqlData sqlData, Object... params) throws Exception {
        return null;
    }

    @Override
    public <E> E select(SqlData sqlData, Object... params) throws Exception {
        return null;
    }

    @Override
    public <E> E insert(SqlData sqlData, Object... params) throws Exception {
        return null;
    }

    @Override
    public <E> E update(SqlData sqlData, Object... params) throws Exception {
        return null;
    }

    @Override
    public <E> E delete(SqlData sqlData, Object... params) throws Exception {
        return null;
    }

    @Override
    public <T> T getMapper(Class<?> mapperType) throws PropertyVetoException, DocumentException {

        //生成代理，通过代理处理你想要的结果
        Object instance =Proxy.newProxyInstance(mapperType.getClassLoader(), new Class[]{mapperType}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //获得method的名字和类，拼接之后得到sql的数据，拿到sql的数据去执行相应的逻辑
                String methodName = method.getName();
                String className = method.getDeclaringClass().getName();
                Type genericReturnType = method.getGenericReturnType();

                String key = className+"."+methodName;
                SqlData sqlData = configuration.getMap().get(key);

                String sqlType = sqlData.getType();

                if ("insert".equals(sqlType))
                {
                    return insert(sqlData,args);
                }else if ("update".equals(sqlType))
                {
                    return update(sqlData,args);
                } else if ("delete".equals(sqlType)) {
                    return delete(sqlData,args);
                }

                //参数化类型
                if (genericReturnType instanceof ParameterizedType)
                {
                    return selectList(sqlData,args);
                }else
                {
                    return select(sqlData,args);
                }

            }
        });

        return (T) instance;
    }
}
